﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

using iESELibrary.DESCrypto.Vault;

namespace iESELibrary.RC4Crypto.Vault
{
	public class PekKey : IDisposable
	{
		#region Constants
		private const int PEK_MD5_ITERATIONS = 1000;
		#endregion

		#region Variables
		private bool disposed = false;
		private byte[] key;
		private byte[] encryptedPek;
		#endregion

		#region Properties
		public byte[] Key
		{
			get
			{
				return this.key;
			}
		}
		#endregion

		#region Constructors
		public PekKey(byte[] encryptedPek, SysKey sysKey)
		{
			this.encryptedPek = encryptedPek;
			this.Decrypt(sysKey);
		}
		#endregion

		#region Enums
		#endregion

		#region Private Methods
		private void Decrypt(SysKey sysKey)
		{
			using (MD5 hashMD5 = MD5.Create())
			{
				byte[] encPekLow = new byte[16];
				byte[] encPekHigh = new byte[this.encryptedPek.Length - 24];

				Array.Copy(this.encryptedPek, 8, encPekLow, 0, 16);
				Array.Copy(this.encryptedPek, 24, encPekHigh, 0, this.encryptedPek.Length - 24);

				hashMD5.TransformBlock(sysKey.BootKey, 0, 16, sysKey.BootKey, 0);

				for (int i = 1; i <= PEK_MD5_ITERATIONS; i++)
				{
					if (i != PEK_MD5_ITERATIONS)
					{
						hashMD5.TransformBlock(encPekLow, 0, 16, encPekLow, 0);
					}
					else
					{
						hashMD5.TransformFinalBlock(encPekLow, 0, 16);
					}
				}

				RC4Crypto.Decryption.Encrypt(ref encPekHigh, hashMD5.Hash);
				//string hex = BitConverter.ToString(encPekHigh);

				this.key = new byte[encPekHigh.Length - 36];
				System.Buffer.BlockCopy(encPekHigh, 36, this.key, 0, encPekHigh.Length - 36);
			}
		}

		#endregion

		#region IDisposable Members
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!this.disposed)
			{
				if (disposing)
				{

				}

				this.disposed = true;
			}
		}
		#endregion
	}
}
